﻿/*
 * This file is part of quickReminder, a software for gamers
 *
 * Copyright (C) 2006-2009 Lucas Romero
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.IO;
using System.Xml.Serialization;

using ICSharpCode.SharpZipLib.Zip;
using LucasCode.PublicTypes;

namespace LucasCode.Tools
{
    public class FileSerializer
    {
        private static ZipFile m_ZipFile;
        private static string m_ZipPath;

        private FileSerializer()
        { }

        public static MatchArchive loadMatchArchiveFromQmaFile(string file)
        {
            System.Diagnostics.Trace.WriteLine("Loading MatchArchive from " + file);

            int XmlDetailsIndex;

            m_ZipFile = null;

            try
            {
                m_ZipFile = new ZipFile(file);
            }
            catch
            {
                return null;
            }
            if ((XmlDetailsIndex = m_ZipFile.FindEntry("matcharchive", true)) >= 0)
            {
                XmlSerializer xml = new XmlSerializer(typeof(MatchArchive));
                using (m_ZipFile.GetInputStream(XmlDetailsIndex))
                {
                    MatchArchive archive = (MatchArchive)xml.Deserialize(m_ZipFile.GetInputStream(XmlDetailsIndex));
                    archive.Initialize(archive);

                    return archive;
                }
            }
            
            return null;
        }

        public static void writeArchiveToZipFile(string path, MatchArchive archive)
        {
            if (!Directory.Exists(Path.GetDirectoryName(path)))
                Directory.CreateDirectory(Path.GetDirectoryName(path));

            if (!File.Exists(path))
            {
                System.Diagnostics.Trace.WriteLine("Creating new ZipFile: " + path + " for archive vs " + archive.Enemy.Name);

                using (m_ZipFile = ZipFile.Create(path))
                {
                    m_ZipFile.BeginUpdate();
                    m_ZipFile.Add(archive, "matcharchive", CompressionMethod.Deflated);
                    m_ZipFile.CommitUpdate();

                    m_ZipPath = path;
                }

                System.Diagnostics.Trace.WriteLine("Creating new ZipFile successful finished");
            }
            else
            {
                System.Diagnostics.Trace.WriteLine("ZipFile already exists, start adding matchArchive to zip");
                
                using (m_ZipFile = new ZipFile(new FileStream(m_ZipPath, FileMode.Open, FileAccess.Read, FileShare.Read)))    
                {
                    m_ZipFile.BeginUpdate();
                    m_ZipFile.Add(archive, "matcharchive", CompressionMethod.Deflated);
                    m_ZipFile.CommitUpdate();
                }

                System.Diagnostics.Trace.WriteLine("Updating existing ZipFile successful finished");
            }
        }

        public static bool addMatchFileToZipArchive(MatchFile file, string path)
        {
            if (!Directory.Exists(Path.GetDirectoryName(path)))
                Directory.CreateDirectory(Path.GetDirectoryName(path));

            System.Diagnostics.Trace.WriteLine("Trying to add MatchFile " + file.Filename + " to the ZipArchive");

            if (!File.Exists(file.Filename))
                throw new FileNotFoundException("Inputfile not found");

            file.DateArchived = DateTime.Now;

            if (!File.Exists(path))
            {
                System.Diagnostics.Trace.WriteLine("Creating new ZipFile: " + path + " for matchfile " + file.Filename);

                using (m_ZipFile = ZipFile.Create(path))
                {
                    m_ZipFile.BeginUpdate();
                    m_ZipFile.Add(file, file.TargetName + DiskIO.getExtension(file.Filename), CompressionMethod.Deflated);
                    m_ZipFile.CommitUpdate();
                    m_ZipPath = path;
                }

                System.Diagnostics.Trace.WriteLine("Creating new ZipFile successful finished");
            }
            else
            {
                System.Diagnostics.Trace.WriteLine("ZipFile already exists, start adding matchFile " + file.Filename +
                                                   " to zip");

                using (m_ZipFile = new ZipFile(new FileStream(m_ZipPath, FileMode.Open, FileAccess.Read, FileShare.Read)))
                {
                    m_ZipFile.BeginUpdate();
                    m_ZipFile.Add(file, file.TargetName + DiskIO.getExtension(file.Filename), CompressionMethod.Deflated);
                    m_ZipFile.CommitUpdate();
                }
            }

            if (string.IsNullOrEmpty(file.OldFilename))
                file.OldFilename = file.Filename;

            file.Filename = file.TargetName + DiskIO.getExtension(file.Filename);

            return true;
        }

        public static bool IsFileArchived(string file)
        {
            if (string.IsNullOrEmpty(m_ZipPath))
                return false;

            int index = -1;

            using (m_ZipFile = new ZipFile(new FileStream(m_ZipPath, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                index = m_ZipFile.FindEntry(file, true);
            }
            if (index >= 0)
                return true;
            else
                return false;
        }
    }
}
